package com.jddup.program.dao.handler.impl;

import com.jddup.common.exception.JddupException;
import com.jddup.common.pojo.TableMeta;
import com.jddup.program.dao.handler.IInsertHandler;
import com.jddup.program.dao.sqlbuilder.InsertPrepareSQLBuilder;
import com.jddup.program.dao.statement.IInsertPrepareStatementSetter;
import com.jddup.program.etm.EntityToTableMetaConvertor;

import java.lang.reflect.InvocationTargetException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;

/**
 * Created by ZZB on 2017/10/8.
 */
public class InsertHandlerImpl implements IInsertHandler {
	private InsertPrepareSQLBuilder insertPrepareSQLBuilder;
	private IInsertPrepareStatementSetter insertPrepareStatementSetter;
	private EntityToTableMetaConvertor entityToTableMetaConvertor;

	public InsertHandlerImpl(InsertPrepareSQLBuilder insertPrepareSQLBuilder,
							 IInsertPrepareStatementSetter insertPrepareStatementSetter, EntityToTableMetaConvertor entityToTableMetaConvertor) {
		this.insertPrepareSQLBuilder = insertPrepareSQLBuilder;
		this.insertPrepareStatementSetter = insertPrepareStatementSetter;
		this.entityToTableMetaConvertor = entityToTableMetaConvertor;
	}

	@Override
	public int insert(Object o, Connection connection) throws JddupException {
		TableMeta tableMeta = entityToTableMetaConvertor.convertFromClass(o.getClass());
		String insertSQL = insertPrepareSQLBuilder.buildInsertSQL(tableMeta);
		if (insertSQL == null) {
			return 0;
		}
		try {
			PreparedStatement preparedStatement = connection.prepareStatement(insertSQL);
			insertPrepareStatementSetter.setInPrepareStatement(preparedStatement, tableMeta, o);
			return preparedStatement.executeUpdate();
		} catch (SQLException | InvocationTargetException | IllegalAccessException | NoSuchMethodException
				| NoSuchFieldException e) {
			throw new JddupException(e);
		}
	}

	@Override
	public int insert(Object o, String tableName, Connection connection) {
		TableMeta tableMeta = entityToTableMetaConvertor.convertFromClass(o.getClass());
		tableMeta.setTableName(tableName);
		String insertSQL = insertPrepareSQLBuilder.buildInsertSQL(tableMeta);
		if (insertSQL == null)
			return 0;
		try {
			PreparedStatement preparedStatement = connection.prepareStatement(insertSQL);
			insertPrepareStatementSetter.setInPrepareStatement(preparedStatement, tableMeta, o);
			return preparedStatement.executeUpdate();
		} catch (SQLException | InvocationTargetException | IllegalAccessException | NoSuchMethodException
				| NoSuchFieldException e) {
			throw new JddupException(e);
		}
	}

	@Override
	public int[] insertList(List<?> objects, Connection connection) throws JddupException {
		TableMeta tableMeta = entityToTableMetaConvertor.convertFromClass(objects.get(0).getClass());
		String insertSQL = insertPrepareSQLBuilder.buildInsertSQL(tableMeta);
		if (insertSQL == null)
			return new int[] { 0 };
		try {
			PreparedStatement preparedStatement = connection.prepareStatement(insertSQL);
			insertPrepareStatementSetter.setBatchInPrepareStatement(preparedStatement, tableMeta, objects);
			return preparedStatement.executeBatch();
		} catch (SQLException | NoSuchMethodException | NoSuchFieldException | IllegalAccessException
				| InvocationTargetException e) {
			throw new JddupException(e);
		}
	}

	@Override
	public int[] insertList(List<?> objects, String tableName, Connection connection) {
		TableMeta tableMeta = entityToTableMetaConvertor.convertFromClass(objects.get(0).getClass());
		tableMeta.setTableName(tableName);
		String insertSQL = insertPrepareSQLBuilder.buildInsertSQL(tableMeta);
		if (insertSQL == null)
			return new int[] { 0 };
		try {
			PreparedStatement preparedStatement = connection.prepareStatement(insertSQL);
			insertPrepareStatementSetter.setBatchInPrepareStatement(preparedStatement, tableMeta, objects);
			return preparedStatement.executeBatch();
		} catch (SQLException | NoSuchMethodException | NoSuchFieldException | IllegalAccessException
				| InvocationTargetException e) {
			throw new JddupException(e);
		}
	}
}
